package lk.mrt.cse.wihidum.client;

import org.apache.axis2.client.*;
import org.apache.axis2.context.MessageContext;
import org.apache.axis2.addressing.*;
import org.apache.axis2.wsdl.WSDLConstants;
import org.apache.axiom.soap.*;
import org.apache.axiom.om.*;
import org.apache.log4j.Logger;
import lk.mrt.cse.wihidum.util.*;

import javax.xml.namespace.QName;
import java.util.Iterator;


/**
 * Created by IntelliJ IDEA.
 * User: Hasini
 * Date: Mar 30, 2010
 * Time: 11:20:36 PM
 * To change this template use File | Settings | File Templates.
 */
public class BrokerRetrievalClient
{
    private static final Logger logger = Logger.getLogger (BrokerList.class);
    public void retrieveBrokers(String adminAddress, String subscriberAddress)
    {
        SOAPEnvelope responseEnvelope=null;
        try
        {
            ServiceClient serviceClient=new ServiceClient();
            OperationClient opClient=serviceClient.createClient(ServiceClient.ANON_OUT_IN_OP);

            MessageContext outMsg=new MessageContext();
            Options opts=outMsg.getOptions();
            opts.setAction(WihidumConstants.Operations.GET_BROKER);
            opts.setTo(new EndpointReference(adminAddress));

            SOAPEnvelope getBrokerRequestEnvelope=createGetBrokerRequestEnvelope(subscriberAddress);
            outMsg.setEnvelope(getBrokerRequestEnvelope);
            opClient.addMessageContext(outMsg);
            opClient.execute(true);
            MessageContext inMsgtCtx = opClient.getMessageContext(WSDLConstants.MESSAGE_LABEL_IN_VALUE);

            responseEnvelope = inMsgtCtx.getEnvelope();
            processGetBrokersMessage(responseEnvelope,WSEventingConstants.ElementNames.GetBrokerResponse);

        }
        catch(Exception e)
        {
            e.printStackTrace();
        }

            
    }
    public void processGetBrokersMessage(SOAPEnvelope message,String messageType)
    {
        OMElement getBrokerResponseElement=message.getBody().getFirstChildWithName(new QName(WSEventingConstants.WIHIDUM_NAMESPACE,messageType));
        OMElement brokerListElement=getBrokerResponseElement.getFirstChildWithName(new QName(WSEventingConstants.WIHIDUM_NAMESPACE,WSEventingConstants.ElementNames.BrokerList));
        //if this is a update message, earlier broker list should be cleared.
        if(!BrokerList.isEmpty())
        {
            BrokerList.clearBrokerList();
        }

        for(Iterator<OMElement> brokerElementIterator=brokerListElement.getChildrenWithName(new QName(WSEventingConstants.WIHIDUM_NAMESPACE,WSEventingConstants.ElementNames.Broker));brokerElementIterator.hasNext();)
        {
            OMElement brokerElement=brokerElementIterator.next();
            String brokerAddress=brokerElement.getText();
            logger.info("Broker "+brokerAddress+" is added to client's broker list.");
            BrokerList.addBrokerToList(brokerAddress);
        }

    }

    private SOAPEnvelope createGetBrokerRequestEnvelope(String subscriberAddress)
    {
        SOAPFactory factory=OMAbstractFactory.getSOAP12Factory();
        SOAPEnvelope getBrokerRequestEnvelope=factory.getDefaultEnvelope();
        //declare namespaces
        OMNamespace wsaNS=factory.createOMNamespace(WSEventingConstants.ADDRESSING_NAMESPACE,WSEventingConstants.ADDRESSING_PREFIX);
        getBrokerRequestEnvelope.declareNamespace(wsaNS);
        OMNamespace wihidumNS=factory.createOMNamespace(WSEventingConstants.WIHIDUM_NAMESPACE,WSEventingConstants.WHIDUM_NAMESPACE_PREFIX);
        getBrokerRequestEnvelope.declareNamespace(wihidumNS);
        SOAPHeader soapHeader=getBrokerRequestEnvelope.getHeader();

        OMElement getBrokerElement=factory.createOMElement(WSEventingConstants.ElementNames.GetBroker,wihidumNS);
        OMElement identifierElement=factory.createOMElement(WSEventingConstants.ElementNames.Identifier,wihidumNS);
        identifierElement.setText(subscriberAddress);

        getBrokerElement.addChild(identifierElement);
        getBrokerRequestEnvelope.getBody().addChild(getBrokerElement);
        
        return getBrokerRequestEnvelope;
    }
}
